package swingExtended.todoQueue;

/**
 *
 * @author g1wshimu
 */
/*
 * TaskStack.java
 *
 * Created on Jul 25, 2013, 4:42:36 PM
 */
import java.awt.LayoutManager;
import function.unary.UnaryFunction;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import list.functions.ListFunctions;
import swingExtended.todoQueue.taskListener.TaskManagerListener;

/**
 *
 * @author g1wshimu
 */
public class TaskManager<T> extends javax.swing.JPanel {

    private List<Task<T>> TASKS = new ArrayList<Task<T>>();
    private List<TaskManagerListener> LISTENERS = 
            new ArrayList<TaskManagerListener>();
    
    /** Creates new form TaskStack */
    public TaskManager() {
        super.setLayout(new javax.swing.BoxLayout(this, 
                javax.swing.BoxLayout.PAGE_AXIS));
    }

    @Override
    public void setLayout(LayoutManager mgr) {
        // Does nothing, don't want the user to override the layout
        // since it's already been set to BoxLayout
    }

    public void addListener(TaskManagerListener listener) {
        LISTENERS.add(listener);
    }
    
    public void removeListener(TaskManagerListener listener) {
        LISTENERS.add(listener);
    }
    
    public boolean hasItems() {
        return getItemCount() > 0;
    }
    
    public int getItemCount() {
        return TASKS.size();
    }

    public void addItem(T data) {
        Task lastTask = ListFunctions.last(TASKS);
        Task newTask = new Task(this, data);

        TASKS.add(newTask);
        newTask.setIndex(TASKS.size() - 1);
        
        if (lastTask != null) {
            lastTask.positionChanged();
        }
        newTask.positionChanged();
        
        this.add(newTask);
        for (TaskManagerListener listener : LISTENERS) {
            listener.onAdd(data);
        }
        refresh();
    }

    public void swapItem(int i, int j) {
        Task t1 = TASKS.get(i),
                t2 = TASKS.get(j);
        t1.setIndex(j);
        t1.positionChanged();
        t2.setIndex(i);
        t2.positionChanged();
        
        ListFunctions.swap(TASKS, i, j);
        //t1.refresh();
        //t2.refresh();
        addAll();
    }

    public void removeItem(int index) {
        TASKS.remove(index);
        for (int i = index; i < TASKS.size(); i++) {
            TASKS.get(i).setIndex(i);
        }
        if (!TASKS.isEmpty()) {
            ListFunctions.first(TASKS).positionChanged();
            ListFunctions.last(TASKS).positionChanged();
        }
        addAll();
    }
    
    public Task<T> getItem(int i) {
        return TASKS.get(i);
    }

    private void refresh() {
        this.repaint();
    }

    private void addAll() {
        this.removeAll();
        for (Task comp : TASKS) {
            this.add(comp);
        }
        this.add(javax.swing.Box.createVerticalGlue());
        refresh();
    }

    public Iterator<T> getTasks() {
        return ListFunctions.map(new UnaryFunction<Task<T>, T>(){

            @Override
            public T evaluate(Task<T> t) {
                return t.getData();
            }
        }, TASKS).iterator();
    }
}

